using hao_Common.Http.Interfaces;
using hao_Common.Http.Options;
using hao_Common.Http.Services;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Polly;
using Polly.Extensions.Http;

namespace hao_Common.Http.Extensions
{
    /// <summary>
    /// 服务集合扩展类
    /// 提供HTTP助手服务注册的扩展方法
    /// </summary>
    public static class ServiceCollectionExtensions
    {
        /// <summary>
        /// 添加HTTP助手服务到依赖注入容器
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="configuration">配置对象</param>
        /// <returns>返回服务集合，支持链式调用</returns>
        public static IServiceCollection AddHttpHelper(this IServiceCollection services, IConfiguration configuration)
        {
            // 绑定配置选项
            services.Configure<HttpClientOptions>(options =>
            {
                configuration.GetSection(HttpClientOptions.SectionName).Bind(options);
            });

            // 获取配置选项
            var httpClientOptions = new HttpClientOptions();
            configuration.GetSection(HttpClientOptions.SectionName).Bind(httpClientOptions);

            // 注册HttpClient with Polly policies
            services.AddHttpClient<IHttpHelper, HttpHelper>(client =>
            {
                client.Timeout = TimeSpan.FromSeconds(httpClientOptions.TimeoutSeconds);
                
                // 添加默认请求头
                foreach (var header in httpClientOptions.DefaultHeaders)
                {
                    client.DefaultRequestHeaders.Add(header.Key, header.Value);
                }
            })
            .AddPolicyHandler(GetRetryPolicy(httpClientOptions))
            .AddPolicyHandler(GetCircuitBreakerPolicy(httpClientOptions));

            return services;
        }

        /// <summary>
        /// 获取重试策略
        /// </summary>
        private static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy(HttpClientOptions options)
        {
            return HttpPolicyExtensions
                .HandleTransientHttpError()
                .WaitAndRetryAsync(
                    retryCount: options.RetryCount,
                    sleepDurationProvider: retryAttempt => TimeSpan.FromMilliseconds(options.RetryDelayMilliseconds * retryAttempt));
        }

        /// <summary>
        /// 获取熔断器策略
        /// </summary>
        private static IAsyncPolicy<HttpResponseMessage> GetCircuitBreakerPolicy(HttpClientOptions options)
        {
            return HttpPolicyExtensions
                .HandleTransientHttpError()
                .CircuitBreakerAsync(
                    handledEventsAllowedBeforeBreaking: options.CircuitBreakerFailureThreshold,
                    durationOfBreak: TimeSpan.FromSeconds(options.CircuitBreakerDurationSeconds));
        }
    }
}